<?php

namespace App\Http\Controllers\Api;

use App\Common\Libs\ArrayHelper;
use App\Consts\GlobalConst;
use App\Consts\GlobalDynamicConst;
use App\Consts\GlobalUserConst;
use App\Exceptions\Error;
use App\Http\Controllers\BaseController;
use App\Models\Cache\CacheKey;
use App\Models\Field\UserField;
use App\Models\Select\UserSelect;
use Illuminate\Http\Request;

class UserController extends BaseController
{
    public $validate = [
        "avatar" => ["rules" => [
            "id" => "required|string|max:24",
            "file" => "required|file",
        ]],
        "changePhone" => ["rules" => [
            "code" => "required|string|max:1000",
            "phone" => "required|string|max:1000",
        ]],
        "dynamicList" => ["rules" => [
            "last_id" => "max:24",
        ]],
        "edit" => ["rules" => [
            "id" => "required|string|max:24",
            "nickname" => "max:15",
            "special_signature" => "max:20",
            "gender" => "in:1,2,3",
        ]],
        "getDetail" => ["rules" => [
            "id" => "string|max:24",
        ]],
        "getInfo" => ["rules" => [
            "id" => "string|max:24",
        ]],
        "likeList" => ["rules" => [
            "id" => "sometimes|required|string|max:24",
        ]],
        "noteList" => ["rules" => [
            "id" => "sometimes|required|string|max:24",
            "last_id" => "max:24",
        ]],
        "packageList" => ["rules" => [
            "id" => "sometimes|required|string|max:24",
            "last_id" => "max:24",
        ]],
        "rePwd" => [
            "rules" => [
                "code" => "required|string|max:6",
                "pwd" => "required|string|max:16|pattern_password",
                "confirm_pwd" => "required|string|max:16|same:pwd|pattern_password",
            ],
        ],
        "unbindWx" => []
    ];

    /**
     * @path /user/article-list
     * @category 用户
     * @title 【有备注】文章列表
     * @method POST
     * @params [{"name":"id","type":"text","required":0,"example":"","desc":"被查看的用户ID，查看自己时可不传"},{"name":"last_id","type":"text","required":0,"example":"","desc":"【翻页时必传】当前页最后一条记录的ID"}]
     * @resBody {"success":true,"statusCode":200,"message":"操作成功","result":{"have_more":true,"list":[{"id":"原创文章ID","type":"类型，1推荐，2原创","cover_url":"文章封面图，如1.jpg","title":"文章标题","description":"文章描述","is_deleted":0,"is_shield":0,"created_at":"创建时间戳","target_type":1,"author":{"id":"用户ID","nickname":"用户昵称","avatar":"用户头像，如1.jpg"},"recommend":["1.jpg"],"count":{"collect":"收藏数","note":"笔记数","recommend":"推荐数"}}]}}
     * @description 1.【前端】此列表只包含【原创文章】
     */
    public function articleList(Request $request)
    {
        $params = $request->all();
        $params = $this->getBaseInfo($params);
        $params['author_id'] = $params['id'] ?? $params['user_id'];

        $data = service()->ArticleService->getUserArticleList($params);

        return $this->apiReturn($data);
    }

    /**
     * @path /user/like-list
     * @category 用户
     * @title 【有备注】点赞列表
     * @method POST
     * @params [{"name":"id","type":"text","required":0,"example":"","desc":"被查看的用户ID，查看自己时可不传"},{"name":"last_id","type":"text","required":0,"example":"","desc":"【翻页时必传】当前页最后一条记录的ID"}]
     * @resBody {"success":true,"statusCode":200,"message":"操作成功","result":{"have_more":true,"list":[{"id":"文章ID","cover_url":"文章封面图","title":"文章标题","description":"文章描述","is_deleted":0,"is_shield":0,"created_at":"10位时间戳","like_id":"收藏ID，此字段作为翻页依据","package_id":"点赞ID","target_type":1},{"id":"文章笔记或划线笔记ID","like_id":"收藏ID，此字段作为翻页依据","type":"笔记类型，1文章笔记，2划线笔记，3随手记","user_id":"用户ID","article_id":"文章ID","is_deleted":0,"is_public":1,"created_at":"创建时间戳","start_index":"文章节选开始索引","end_index":"文章节选结束索引","content":"笔记内容","selected":"文章节选内容","is_like":0,"is_collect":1,"user":{"id":"用户ID","nickname":"用户昵称","avatar":"头像，如1.jpg"},"article":{"id":"文章ID","cover_url":"文章封面图，如1.jpg","title":"文章标题","description":"文章描述","is_deleted":0,"is_shield":0,"created_at":"文章创建时间戳"},"count":{"comment":"评论数","like":"点赞数","collect":"收藏数"}},{"id":"文章笔记或划线笔记ID","like_id":"收藏ID，此字段作为翻页依据","type":"笔记类型，1文章笔记，2划线笔记，3随手记","user_id":"用户ID","article_id":"文章ID","is_deleted":0,"is_public":1,"created_at":"创建时间戳","start_index":"文章节选开始索引","end_index":"文章节选结束索引","content":"笔记内容","selected":"文章节选内容","is_like":0,"is_collect":1,"user":{"id":"24位用户ID","nickname":"用户昵称","avatar":"头像，如1.jpg"},"image":["1.jpg"],"article":{},"count":{"comment":"评论数","like":"点赞数","collect":"收藏数"}}]}}
     * @description 1.【前端】翻页时，传的<last_id>是返回字段中的like_id
     */
    public function likeList(Request $request)
    {
        $searchParams = $request->all();

        $searchParams = ArrayHelper::merge($searchParams, [
            'sender_id' => array_key_exists('id', $searchParams) ? $searchParams['id'] : $this->getCurrentUserId(),
            'current_user_id' => $this->getCurrentUserId(),
        ]);


        $likeList = service()->LikeService->getUserLikeList($searchParams);

        return $this->apiReturn($likeList);
    }

    /**
     * @path /user/note-list
     * @category 用户
     * @title 笔记列表
     * @method POST
     * @params [{"name":"id","type":"text","required":0,"example":"","desc":"被查看的用户ID，查看自己时可不传"},{"name":"last_id","type":"text","required":0,"example":"","desc":"【翻页时必传】当前页最后一条记录的ID"}]
     * @resBody {"success":true,"statusCode":200,"message":"操作成功","result":{"have_more":false,"list":[{"id":"24位文章笔记或划线笔记ID","type":"笔记类型，1文章笔记，2划线笔记，3随手记","user_id":"24位用户ID","article_id":"24位文章ID","is_deleted":0,"is_public":1,"created_at":"10位时间戳","start_index":"文章节选开始索引","end_index":"文章节选结束索引","content":"笔记内容","selected":"文章节选内容","is_like":0,"is_collect":1,"user":{"id":"24位用户ID","nickname":"用户昵称","avatar":"头像，如1.jpg"},"article":{"id":"24位文章ID","cover_url":"文章封面图，如1.jpg","title":"文章标题","description":"文章描述","is_deleted":0,"is_shield":0,"created_at":"文章创建时间戳"},"count":{"comment":"评论数","like":"点赞数","collect":"收藏数"}},{"id":"24位随手记ID","type":"笔记类型，1文章笔记，2划线笔记，3随手记","user_id":"24位用户ID","article_id":"","is_deleted":0,"is_public":1,"created_at":"10位时间戳","start_index":0,"end_index":0,"content":"笔记内容","selected":"","is_like":0,"is_collect":1,"user":{"id":"24位用户ID","nickname":"用户昵称","avatar":"头像，如1.jpg"},"article":{},"image":["1.jpg","2.jpg"],"count":{"comment":"评论数","like":"点赞数","collect":"收藏数"}}]}}
     */
    public function noteList(Request $request)
    {
        $params = $request->all();

        $data = service()->NoteService->userNoteList($this->getBaseInfo($params, [
            'user_id' => array_key_exists('id', $params) ? $params['id'] : $this->getCurrentUserId(),
        ]));

        return $this->apiReturn($data);
    }

    /**
     * @path /user/package-list
     * @category 用户
     * @title 收藏夹列表
     * @method POST
     * @params [{"name":"id","type":"text","required":0,"example":"","desc":"被查看的用户ID，查看自己时可不传"},{"name":"last_id","type":"text","required":0,"example":"","desc":"【翻页时必传】当前页最后一条记录的ID"}]
     * @resBody {"success":true,"statusCode":200,"message":"操作成功","result":{"have_more":true,"list":[{"id":"收藏夹ID","user_id":"用户ID","name":"收藏夹名称","description":"收藏夹描述","total":"收藏夹内容总数","is_default":1,"is_deleted":0,"is_public":1,"updated_at":"收藏夹最后更新时间"}]}}
     */
    public function packageList(Request $request)
    {
        $params = $request->all();

        $searchParams = [
            'user_id' => array_key_exists('id', $params) ? $params['id'] : $this->getCurrentUserId(),
            'current_user_id' => $this->getCurrentUserId(),
        ];
        if (array_key_exists('last_id', $params)) {
            $searchParams['last_id'] = $params['last_id'];
        }

        $collectPackageList = service()->PackageService->getUserCollectPackageList($searchParams);

        return $this->apiReturn($collectPackageList);
    }

    /**
     * @path /user/dynamic-list
     * @category 用户
     * @title 动态列表
     * @method POST
     * @params [{"name":"id","type":"text","required":0,"example":"","desc":"被查看的用户ID，查看自己时可不传"},{"name":"last_id","type":"text","required":0,"example":"","desc":"【翻页时必传】当前页最后一条记录的ID"}]
     * @resBody {"success":true,"statusCode":200,"message":"操作成功","result":{"have_more":true,"list":[{"id":"动态ID","type":"动态类型，1原创文章动态，2笔记动态，3推荐文章动态，4话题动态","is_deleted":0,"created_at":"","article":{"id":"推荐文章ID","type":"类型，1推荐，2原创","cover_url":"文章封面图，如1.jpg","title":"文章标题","description":"文章描述","is_deleted":0,"is_shield":0,"created_at":"创建时间戳","target_type":1,"author":{},"count":{"collect":"收藏数","note":"笔记数","recommend":"推荐数"}}},{"id":"动态ID","type":"动态类型，1原创文章动态，2笔记动态，3推荐文章动态，4话题动态","is_deleted":0,"created_at":"","article":{"id":"原创文章ID","type":"类型，1推荐，2原创","cover_url":"文章封面图，如1.jpg","title":"文章标题","description":"文章描述","is_deleted":0,"is_shield":0,"created_at":"创建时间戳","target_type":1,"author":{"id":"24位用户ID","nickname":"用户昵称","avatar":"头像，如1.jpg"},"count":{"collect":"收藏数","note":"笔记数","recommend":"推荐数"}}},{"id":"动态ID","type":"动态类型，1原创文章动态，2笔记动态，3推荐文章动态，4话题动态","is_deleted":0,"created_at":"","note":{"id":"24位文章笔记或划线笔记ID","type":"笔记类型，1文章笔记，2划线笔记，3随手记","user_id":"24位用户ID","article_id":"24位文章ID","is_deleted":0,"is_public":1,"created_at":"10位时间戳","start_index":"文章节选开始索引","end_index":"文章节选结束索引","content":"笔记内容","selected":"文章节选内容","is_like":0,"is_collect":1,"user":{"id":"24位用户ID","nickname":"用户昵称","avatar":"头像，如1.jpg"},"article":{"id":"24位文章ID","cover_url":"文章封面图，如1.jpg","title":"文章标题","description":"文章描述","is_deleted":0,"is_shield":0,"created_at":"文章创建时间戳"},"count":{"comment":"评论数","like":"点赞数","collect":"收藏数"}}},{"id":"动态ID","type":"动态类型，1原创文章动态，2笔记动态，3推荐文章动态，4话题动态","is_deleted":0,"created_at":"","note":{"id":"24位随手记ID","type":"笔记类型，1文章笔记，2划线笔记，3随手记","user_id":"24位用户ID","article_id":"","is_deleted":0,"is_public":1,"created_at":"10位时间戳","start_index":0,"end_index":0,"content":"笔记内容","selected":"","is_like":0,"is_collect":1,"user":{"id":"24位用户ID","nickname":"用户昵称","avatar":"头像，如1.jpg"},"article":{},"image":["1.jpg","2.jpg"],"count":{"comment":"评论数","like":"点赞数","collect":"收藏数"}}}]}}
     */
    public function dynamicList(Request $request)
    {
        $params = $this->getBaseInfo($request->all());

        $data = service()->DynamicService->getUserDynamicList($this->getBaseInfo($params, [
            'user_id' => array_key_exists('id', $params) ? $params['id'] : $this->getCurrentUserId(),
            'is_deleted' => GlobalConst::IS_NOT_DELETE,
            'is_view' => $this->getCurrentUserId() === ($params['id'] ?? 0)
                ? [GlobalDynamicConst::IS_VIEW, GlobalDynamicConst::IS_NOT_VIEW] : GlobalDynamicConst::IS_VIEW,
        ]));

        return $this->apiReturn($data);
    }

    /**
     * @path /user/dynamic-landing
     * @category 落地页
     * @title 用户详情 - 动态列表
     * @method POST
     * @params [{"name":"id","type":"text","required":0,"example":"","desc":"被查看的用户ID，查看自己时可不传"},{"name":"last_id","type":"text","required":0,"example":"","desc":"【翻页时必传】当前页最后一条记录的ID"}]
     * @resBody {"success":true,"statusCode":200,"result":{"total_count":1,"page_size":20,"page":1,"list":[{"id":"24位动态ID","target_type":7,"created_at":1604632694,"user":{"id":"24位用户ID","avatar":"default.png","nickname":"听君031233"},"topic":{"id":"","title":"","updated_at":"","count":{"hot":1}}},{"id":"24位动态ID","created_at":1604632694,"target_type":2,"content":"笔记内容","selected":"文章节选","start_index":"文章节选开始位置","end_index":"文章节选结束位置","is_like":"是否点赞，0否，1是","is_collect":"是否收藏，0否，1是","user":{"id":"24位用户ID","avatar":"default.png","nickname":"听君031233"},"count":{"collect":0,"like":0,"comment":0},"article":{"id":"24位文章ID","title":"文章标题","cover_url":"封面图，可能位空值","description":"摘要，可能位空值","is_fail":false,"count":{"like":0,"collect":0}},"note":{"id":"24位笔记ID","content":"笔记内容","type":"笔记类型，1文章笔记，2文章划线笔记，3文本类笔记","selected":"文章节选内容，可能位空值","start_index":1,"end_index":2,"article":{"id":"24位文字ID","title":"文字标题","cover_url":"封面图，可能位空值","description":"摘要","is_fail":false},"image":["1.jpg"],"topic":[{"id":"24位话题ID","title":"话题标题"}]}}]},"message":"OK"}
     */
    public function dynamicLanding(Request $request)
    {
        $params = $this->getBaseInfo($request->all());

        $data = service()->DynamicService->getUserDynamicList($this->getBaseInfo($params, [
            'user_id' => array_key_exists('id', $params) ? $params['id'] : $this->getCurrentUserId(),
            'is_deleted' => GlobalConst::IS_NOT_DELETE,
            'is_view' => $this->getCurrentUserId() === ($params['id'] ?? 0)
                ? [GlobalDynamicConst::IS_VIEW, GlobalDynamicConst::IS_NOT_VIEW] : GlobalDynamicConst::IS_VIEW,
            'is_allow_essay_note' => true,
            'is_allow_topic' => true,
        ]));

        return $this->apiReturn($data);
    }

    /**
     * @path /user/avatar
     * @category 用户
     * @title 修改头像
     * @method POST
     * @params [{"name":"id","type":"text","required":1,"example":"","desc":"用户ID"},{"name":"file","type":"file","required":1,"example":"","desc":"文件资源"}]
     * @resBody {"success":true,"statusCode":200,"result":{"url":"1.jpg"},"message":"OK"}
     */
    public function avatar(Request $request)
    {
        $userId = $request->post('id');

        $updateRes = service()->UserService->updateUserAvatar($this->user, $userId);

        return $this->apiReturn($updateRes);
    }

    /**
     * @path /user/edit
     * @category 用户
     * @title 修改
     * @method POST
     * @params [{"name":"id","type":"text","required":1,"example":"","desc":"用户ID"},{"name":"nickname","type":"text","required":0,"example":"","desc":"昵称"},{"name":"special_signature","type":"text","required":0,"example":"","desc":"个性签名"},{"name":"gender","type":"text","required":0,"example":"","desc":"性别，1男，2女，3保密"},{"name":"birthday","type":"text","required":0,"example":"","desc":"生日时间戳"},{"name":"country","type":"text","required":0,"example":"","desc":"国家ID"},{"name":"province","type":"text","required":0,"example":"","desc":"省ID"},{"name":"city","type":"text","required":0,"example":"","desc":"市ID"},{"name":"industry","type":"text","required":0,"example":"","desc":"行业，按level以逗号隔开"},{"name":"education","type":"text","required":0,"example":"","desc":"学历ID"},{"name":"job","type":"text","required":0,"example":"","desc":"职业，按level以逗号隔开"},{"name":"description","type":"text","required":0,"example":"","desc":"个人简介"}]
     * @resBody {"success":true,"statusCode":200,"result":true,"message":"OK"}
     */
    public function edit(Request $request)
    {
        $params = $request->all();
        $params = $this->filterSignParams($params);

        if (array_key_exists('special_signature', $params)) {
            if (!empty($params['special_signature'])) {
                $params['sign'] = $params['special_signature'];
            } else {
                $params['sign'] = '';
            }
            $params = ArrayHelper::remove($params, ['special_signature']);
        }

        // $params['industry'] = '1,2'
        if (array_key_exists('industry', $params) && !empty($params['industry'])) {
            $industryArr = explode(',', $params['industry']);
            if (count($industryArr) != 2) {
                return $this->apiReturn(Error::handle());
            }
            $params['industry_id'] = $industryArr[count($industryArr) - 1];
            $params['industry_parent_id'] = $industryArr[0];
        }

        if (array_key_exists('job', $params) && !empty($params['job'])) {
            $jobArr = explode(',', $params['job']);
            if (count($jobArr) != 3) {
                return $this->apiReturn(Error::handle());
            }
            $params['job_id'] = $jobArr[count($jobArr) - 1];
            $params['job_parent_id'] = implode(',', array_slice($jobArr, 0, 2));
        }

        if (array_key_exists('education', $params) && !empty($params['education'])) {
            $params['education_id'] = $params['education'];
        }

        if (array_key_exists('education_id', $params) && empty($params['education_id'])) $params = ArrayHelper::remove($params, ['education_id']);
        if (array_key_exists('province', $params) && empty($params['province'])) $params = ArrayHelper::remove($params, ['province']);
        if (array_key_exists('city', $params) && empty($params['city'])) $params = ArrayHelper::remove($params, ['city']);

        $params['user_id'] = $this->getCurrentUserId();

        $params = ArrayHelper::remove($params, ['industry', 'education', 'job']);

        $updateRes = service()->UserService->updateUserInfo($params);

        return $this->apiReturn($updateRes);
    }

    /**
     * @path /user/get-detail
     * @category 用户
     * @title 详情
     * @method POST
     * @params [{"name":"id","type":"text","required":1,"example":"","desc":"用户ID"}]
     * @resBody {"success":true,"statusCode":200,"result":[{"id":"用户ID","identity":"1普通用户，2作者","phone":"手机号","nickname":"用户昵称","avatar":"用户头像，如1.jpg","status":"用户状态，0异常，1正常","special_signature":"个性签名","birthday":"生日时间戳","gender":"性别，1男，2女，3保密","description":"个人简介","province":"省ID","city":"市ID","industry":["1","2"],"job":[],"education":"学历ID","is_new":false,"created_at":"创建时间戳","access_token":"令牌","identity":1,"login_method":"登录方式，1手机号验证码，2手机号密码，3QQ，4微信，5微博","server_time":"服务器时间"}],"message":"OK"}
     */
    public function getDetail(Request $request)
    {
        $params = $request->all();
        $userId = $params['id'] ?? $this->getCurrentUserId();

        // 用户信息
        $user = service()->UserService->getUserByUserId($userId, UserSelect::SELF_DETAIL);
        if (false === $user) {
            return Error::handle(lang('User not exists'));
        }
        $userId = $user->user_id;

        // 计数
        $countArr = $userId == $this->getCurrentUserId() ? ['note', 'article', 'attention', 'fans'] : ['article', 'public_note', 'attention', 'fans'];
        $userCounter = service()->CounterService->getTargetCount(CacheKey::COUNTER_USER, $countArr, ['user_id' => $user->user_id]);

        // 授权信息
        $auth = service()->AuthWxService->getAuthInfoByUserId($userId);

        return $this->apiReturn(ArrayHelper::merge($user->commonFormat(UserField::SELF_DETAIL), [
            'attention_status' => service()->RelationshipService->getAttentionStatus($this->getCurrentUserId(), $userId),
            'have_password' => (int)!isset($user->password_hash),
            'wechat' => [
                'nickname' => $auth->nickname ?? ''
            ],
            'count' => $userCounter,
            'login_method' => service()->LoginService->getLoginMethodByUserIdFromCache($this->getCurrentUserId())
        ]));
    }

    /**
     * @path /user/get-info
     * @category 用户
     * @title 基本信息
     * @method POST
     * @params [{"name":"id","type":"text","required":1,"example":"","desc":"用户ID"}]
     * @resBody {"success":true,"statusCode":200,"result":[{"id":"用户ID","identity":"1普通用户，2作者","phone":"手机号","nickname":"用户昵称","avatar":"用户头像，如1.jpg","status":"用户状态，0异常，1正常","special_signature":"个性签名","birthday":"生日时间戳","gender":"性别，1男，2女，3保密","description":"个人简介","province":"省ID","city":"市ID","industry":["1","2"],"job":[],"education":"学历ID","is_new":false,"created_at":"创建时间戳","access_token":"令牌","identity":1,"login_method":"登录方式，1手机号验证码，2手机号密码，3QQ，4微信，5微博","server_time":"服务器时间"}],"message":"OK"}
     */
    public function getInfo(Request $request)
    {
        $params = $request->all();
        $userId = $params['id'] ?? $this->getCurrentUserId();

        // 用户信息
        $user = service()->UserService->getUserByUserId($userId, UserSelect::SELF_INFO);

        // 计数
        $countArr = $userId == $this->getCurrentUserId() ? ['note', 'self_note', 'public_note', 'attention', 'fans'] : ['self_note', 'dynamic', 'attention', 'fans'];
        $userCounter = service()->CounterService->getTargetCount(CacheKey::COUNTER_USER, $countArr, ['user_id' => $user->user_id]);

        return $this->apiReturn(ArrayHelper::merge($user->commonFormat(UserField::SELF_INFO), [
            'count' => $userCounter,
            'identity' => GlobalUserConst::IDENTITY_USER,
        ]));
    }

    /**
     * @path /user/change-phone
     * @category 用户
     * @title 修改手机号
     * @method POST
     * @params [{"name":"phone","type":"text","required":1,"example":"","desc":"手机号"},{"name":"code","type":"text","required":1,"example":"","desc":"验证码"}]
     * @resBody {"success":true,"statusCode":200,"result":true,"message":"OK"}
     */
    public function changePhone(Request $request)
    {
        $params = $request->all();

        $updateRes = service()->UserService->changeUserPhone($this->user, $params['phone'], $params['code']);

        return $this->apiReturn($updateRes);
    }

    /**
     * @path /user/re-pwd
     * @category 用户
     * @title 修改密码
     * @method POST
     * @params [{"name":"pwd","type":"text","required":1,"example":"","desc":"密码"},{"name":"confirm_pwd","type":"text","required":1,"example":"","desc":"确认密码"},{"name":"code","type":"text","required":1,"example":"","desc":"验证码"}]
     * @resBody {"success":true,"statusCode":200,"result":true,"message":"OK"}
     */
    public function rePwd(Request $request)
    {
        $params = $request->all();

        $changePasswordResult = service()->UserService->changeUserPassword($this->user, $params['code'], $params['pwd']);

        return $this->apiReturn($changePasswordResult);
    }

    /**
     * @path /user/unbind-wx
     * @category 用户
     * @title 解绑微信
     * @method POST
     * @resBody {"success":true,"statusCode":200,"result":true,"message":"OK"}
     */
    public function unbindWx(Request $request)
    {
        $unbindRes = service()->AuthWxService->delAuthByUser($this->user);

        return $this->apiReturn($unbindRes);
    }
}
